#!/usr/bin/php
<?php

include_once('lib/ContextIO/OAuth.php');
include_once('lib/ContextIO/class.contextio.php');
include_once('lib/Dropbox/autoload.php');

class Contextbox {
  private $contextIO; // ContextIO Object
  public $mailbox;    // ContextIO Mailbox

  public $tmpdir;     // Local save directory

  private $oauth;     // Dropbox_Oauth_PHP Object
  private $dropbox;   // Dropbox_API Object
  public $dropboxPath;// Dropbox Remote Path

  function __construct($args=array()) {
    $this->mailbox = $args['contextio_mailbox'];
    $this->dropboxPath = $args['dropbox_path'];
    $this->tmpdir = $args['local_save_dir'];
    if (!is_dir($this->tmpdir.$this->dropboxPath)) mkdir($this->tmpdir.$this->dropboxPath, 0700, true);

    $this->contextIO = new ContextIO($args['contextio_key'], $args['contextio_secret']);
    $this->contextIO->useAuthorizationHeaders(true);

    echo "Requesting new files...\n";
    $r = $this->contextIO->allFiles($this->mailbox, array('since' => time()-900));
    $data = $r->getData();
    if (!empty($data)) {
      $this->oauth = new Dropbox_OAuth_PHP($args['dropbox_key'], $args['dropbox_secret']);
      $this->dropbox = new Dropbox_API($this->oauth);
      $tokens = $this->dropbox->getToken($args['dropbox_username'], $args['dropbox_password']);
      $this->oauth->setToken($tokens);
      try {
        $basePath = $this->dropbox->getMetadata($this->dropboxPath);
        $this->dropbox->createFolder($this->dropboxPath);
      } catch (OAuthException $e) {
        // Folder exists
      }
      foreach ($data as $document) {
        foreach ($document['occurrences'] as $attachment) {
          $filename = $this->getFileName($attachment['subject'], $attachment['fileName']);
          $exists = $this->parseDropbox($filename, $attachment['size'])? true : false;
          if (!$exists) {
            // File does not exist
            $localfile = $this->tmpdir.$filename;
            if (!is_dir(dirname($localfile))) mkdir(dirname($localfile), 0777, true);
            echo "Downloading ".$attachment['fileName']." to $localfile\n";
            $content = $this->contextIO->downloadFile($this->mailbox, array('fileId'=>$attachment['fileId']));
            file_put_contents($localfile, $content);
            try {
              $basePath = $this->dropbox->getMetadata(dirname($filename));
              $this->dropbox->createFolder(dirname($filename));
            } catch (OAuthException $e) {
              // Folder exists
            }
            echo "Uploading $flename to Dropbox...\n";
            $this->dropbox->putFile($filename, $localfile, 'dropbox');
          }
        }
      }
    }
    else { echo "No files found.\n"; }
  }

  public function __destruct() {
    $this->recursiveDelete($this->tmpdir.$this->dropboxPath);
  }

  private function subject_format($subject) {
    $regex = "^(re|fwd): ?";
    $replace = array('re: ', 'fwd: ');
    return str_ireplace($replace, '', $subject);
  }

  private function getFileName($subject, $filename) {
    $filename = $this->dropboxPath.'/'.$this->subject_format($subject.'/'.$filename);
    if (preg_match('=^[^/?*;:{}\\\\]+\.[^/?*;:{}\\\\]+$=', $filename) !== false) $filename = preg_replace('=^[^/?*;:{}\\\\]+\.[^/?*;:{}\\\\]+$=', '_', $filename);
    if (strpos($filename, ' ') !== FALSE) $filename = '"'.$filename.'"';
    return $filename;
  }

  private function parseDropbox($loc, $size) {
    try {
      $data = @$this->dropbox->getMetadata(str_replace('/'.basename($loc), '', $loc));
      return ($data['contents']['0']['size'] == $size)? false : true;
    } catch (OAuthException $e) {
     return false;
    }
  }

  function recursiveDelete($str){
    if (is_file($str)) { return @unlink($str); }
    elseif (is_dir($str)) {
      $scan = glob(rtrim($str,'/').'/*');
      foreach($scan as $index=>$path){ recursiveDelete($path); }
      return @rmdir($str);
    }
  }

}

$args = array('dropbox_username'  => '',
              'dropbox_password'  => '',
              'dropbox_key'       => '',
              'dropbox_secret'    => '',
              'contextio_mailbox' => '',
              'contextio_key'     => '',
              'contextio_secret'  => '',
              'dropbox_path'      => '/Attachments',
              'local_save_dir'    => dirname(__FILE__).'/data',
              'delete_after_send' => true,
              );
new Contextbox($args);